import React, { Component } from 'react'
import { message } from 'antd'
import netmap from './index.module.css'

export default class CameraCapture extends Component {

  constructor(props){
    super(props);
    this.state = {
      stream: null,
      type: 'contain',
      imgSrc: null,

      videoWidth: 0,
      videoHeight: 0,

      recordedBlobs: [], // 视频音频 blobs
      isRecord: false, // 视频是否正在录制
      videoUrl: null,
    };
    this.videoRef = React.createRef()
    this.videoWrapRef = React.createRef()
  }

  componentDidMount(){

    // 老的浏览器可能根本没有实现 mediaDevices，所以我们可以先设置一个空的对象
    if (navigator.mediaDevices === undefined) {
      navigator.mediaDevices = {};
    }

    // 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
    // 因为这样可能会覆盖已有的属性。这里我们只会在没有 getUserMedia 属性的时候添加它。
    if (navigator.mediaDevices.getUserMedia === undefined) {
      navigator.mediaDevices.getUserMedia = function (constraints) {
        // 首先，如果有 getUserMedia 的话，就获得它
        var getUserMedia =
          navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

        // 一些浏览器根本没实现它 - 那么就返回一个 error 到 promise 的 reject 来保持一个统一的接口
        if (!getUserMedia) {
          return Promise.reject(
            new Error("getUserMedia is not implemented in this browser"),
          );
        }

        // 否则，为老的 navigator.getUserMedia 方法包裹一个 Promise
        return new Promise(function (resolve, reject) {
          getUserMedia.call(navigator, constraints, resolve, reject);
        });
      };
    }



    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      // 浏览器不支持 getUserMedia，可能需要引入 Polyfill 或提示用户
      console.log('当前浏览器不支持 getUserMedia API')
    } else {
      // 浏览器支持 getUserMedia，可以正常使用拍照功能
      // 调用相关函数来初始化摄像头等操作
      // 访问用户摄像头设备
      this.initCamera()
    }
  }

  componentDidUpdate(){
  }
  componentWillUnmount(){
    this.closeCamera()
  }

  initCamera = async () => {
    let videoWidth = 640, videoHeight = 480
    if (this.videoWrapRef.current) {
      videoWidth = this.videoWrapRef.current.clientWidth
      videoHeight = this.videoWrapRef.current.clientHeight
    }

    var proportion = videoHeight / videoWidth
    let type = 'contain'
    if(proportion  > 1.3){
      type='cover' //cover	保持原有尺寸比例。但部分内容可能被剪切。
    }else{
      type='contain' //contain	保持原有尺寸比例。内容被缩放
    }
    this.setState({
      type,
      videoWidth,
      videoHeight
    })
    
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ video: { width: videoWidth, height: videoHeight } });
      this.setState({ stream });

      if (this.videoRef.current) {
        // 旧的浏览器可能没有 srcObject
        if ("srcObject" in this.videoRef.current) {
          this.videoRef.current.srcObject = stream;
        } else {
          // 防止在新的浏览器里使用它，应为它已经不再支持了
          this.videoRef.current.src = window.URL.createObjectURL(stream);
        }
        this.videoRef.current.onloadedmetadata =  (e) => {
          this.videoRef.current.play();
        };
      }

    } catch (error) {
      console.error('Error accessing camera: ', error);
      if (error == 'NotFoundError: Requested device not found') {
        message.warning('没有找到摄像头！')
      }
    }
  }

  closeCamera = () => {
    // 关闭摄像头流
    const { stream } = this.state;
    if (stream) {
      stream.getTracks().forEach(track => track.stop());
    }
  }


  // 下载录像
  downloadRecord = () => {
    let a = document.createElement("a");//创建a标签
    a.setAttribute("href", this.state.videoUrl);//设置文件下载地址
    // 生成随机数字
    const rand = Math.floor((Math.random() * 1000000));
    // 生成视频名
    const name = `video${rand}.mp4`;
    // setAttribute() 方法添加指定的属性，并为其赋指定的值
    a.setAttribute('download', name);
    a.setAttribute('name', name);

    document.body.appendChild(a);//添加到body
    a.click();//触发事件
    document.body.removeChild(a);//移除标签


//     // 设置下载链接
//     document.getElementById('downLoadLink').href = this.state.videoUrl;
//     // 设置下载mp4格式视频
//     document.getElementById('downLoadLink').download = 'media.mp4';
//     document.getElementById('downLoadLink').innerHTML = 'DownLoad video file';
//     // 生成随机数字
//     const rand = Math.floor((Math.random() * 1000000));
//     // 生成视频名
//     const name = `video${rand}.mp4`;
    
//     // setAttribute() 方法添加指定的属性，并为其赋指定的值
//     document.getElementById('downLoadLink').setAttribute('download', name);
//     document.getElementById('downLoadLink').setAttribute('name', name);

// // 0.5s后自动下载视频
//     setTimeout(() => {
//       document.getElementById('downLoadLink').click();
//     }, 500);
    
  }

  // 视频录制
  startRecord = () => {

    console.log('record');
    this.setState({ isRecord: true });
    let mediaRecorder;
    let options;
    this.state.recordedBlobs = [];
    if (typeof MediaRecorder.isTypeSupported === 'function') {
      // 根据浏览器来设置编码参数
      if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
        options = {
          MimeType: 'video/webm;codecs=h264',
        };
      } else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
        options = {
          MimeType: 'video/webm;codecs=h264',
        };
      } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
        options = {
          MimeType: 'video/webm;codecs=vp8',
        };
      }
      mediaRecorder = new MediaRecorder(this.state.stream, options);
    } else {
      // console.log('isTypeSupported is not supported, using default codecs for browser');
      console.log('当前不支持isTypeSupported，使用浏览器的默认编解码器');
      mediaRecorder = new MediaRecorder(this.state.stream);
    }
    mediaRecorder.start();
    // 视频录制监听事件
    mediaRecorder.ondataavailable = e => {
      console.log(e);
      // 录制的视频数据有效
      if (e.data && e.data.size > 0) {
        this.state.recordedBlobs.push(e.data);
      }
    };
    // 停止录像后增加下载视频功能，将视频流转为mp4格式
    mediaRecorder.onstop = () => {
      const blob = new Blob(this.state.recordedBlobs, { type: 'video/mp4' });
      this.state.recordedBlobs = [];
      // 将视频链接转换完可以用于在浏览器上预览的本地视频
      const videoUrl = window.URL.createObjectURL(blob);

      console.log(videoUrl);
      this.setState({ videoUrl }, () => {this.props.getVideoUrl(videoUrl)});

    };
  }

  // 停止录制
  stopRecord = () =>{
    if (!this.videoRef.current.srcObject) return;
    const stream = this.videoRef.current.srcObject;
    const tracks = stream.getTracks();
    // 关闭摄像头和音频
    tracks.forEach(track => {
      track.stop();
    });
    this.setState({
      isRecord: false
    }, () => {this.initCamera()})
  }

  render() {
    return (
      <div className={netmap.container}>
        <div className={netmap.video_outer_wrap}>
          {
            !this.state.stream && (
              <div className={netmap.not_found}>没有找到摄像头！</div>
            )
          }
          <div className={netmap.video_wrap} ref={this.videoWrapRef}>
            <video ref={this.videoRef} 
              autoPlay 
              playsInline 
              style={{width: '100%',height: '100%', objectFit: this.state.type}}
            ></video>
          </div>
        </div>
        <div className={netmap.btns}>
          {
            this.state.isRecord ?
              <button className={netmap.btn} onClick={this.stopRecord}>
                停止
              </button>
            :
              <button className={netmap.btn} onClick={this.startRecord}>
                录像
              </button>
          }
          <button className={netmap.btn} onClick={this.downloadRecord}>
            下载录像
          </button>
        </div>
      </div>
    )
  }
}
